package mobile.game.core.support.observer;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import mobile.game.core.support.SysException;
import mobile.game.core.support.function.CommonFunction;

/**
 * @author gaopan
 * 
 * 观察者模式基类
 * 职责
 * 1.初始化
 * 2.发布事件
 * 3.通知观察者
 */
public abstract class Observer {
	/** 事件->处理函数列表 */
	private final Map<String, List<CommonFunction>> eventMethod = new HashMap<>();
	
	/***
	 * 注册事件侦听函数，此函数一般由自动生成的代码调用
	 * @param key
	 * @param function
	 * @param paramSize
	 */
	public final void reg(String key, Object function, int paramSize) {
		List<CommonFunction> funcs = eventMethod.get(key);
		if(null == funcs){
			funcs = new ArrayList<>();
			eventMethod.put(key, funcs);
		}
		
		funcs.add(new CommonFunction(function ,paramSize));
	}

	private void _fireHandler(String fullKey, Object param) {
		List<CommonFunction> funcs = eventMethod.get(fullKey);
		if(null != funcs){
			for(CommonFunction f : funcs){
				f.apply(param);
			}
		}
	}
	
	/**
	 * 发布事件
	 * 如果有子事件 那么会创建两个事件(主事件 + 子事件)
	 * @param key
	 * @param subKey
	 * @param param
	 */
	public final void fireHandler(Object key, Object subKey, Object param) {
		try {
			// 创建事件关键字
			// 如果有子事件 那么会创建两个事件(主事件 + 子事件)
			_fireHandler(createMethodKey(key, null), param);
			if(subKey != null) {
				_fireHandler(createMethodKey(key, subKey), param);
			}
		} catch (Exception e) {
			throw new SysException(e);
		}
	}
	
	/**
	 * 创建事件关键字
	 * 
	 * 虽然fire时是生成了两个事件，但是这里不能
	 * 这个函数不能改成
	 * @param key
	 * @param subKey
	 * @return
	 */
	public static String createMethodKey(Object key, Object subKey) {
		String mk = key.toString();
		
		// 如果有 那么拼装子事件
		if(subKey != null && !subKey.toString().equals("")) {
			mk = mk + "$" + subKey.toString();
		}
		
		return mk;
	}
}